/*     */ package com.zimbra.cs.service.doc;
/*     */ 
/*     */ import com.zimbra.common.account.Key.AccountBy;
/*     */ import com.zimbra.common.httpclient.HttpClientUtil;
/*     */ import com.zimbra.common.mime.ContentType;
/*     */ import com.zimbra.common.mime.MimeDetect;
/*     */ import com.zimbra.common.service.ServiceException;
/*     */ import com.zimbra.common.service.ServiceException.Argument;
/*     */ import com.zimbra.common.service.ServiceException.Argument.Type;
/*     */ import com.zimbra.common.service.ServiceException.InternalArgument;
/*     */ import com.zimbra.common.soap.Element;
/*     */ import com.zimbra.common.soap.MailConstants;
/*     */ import com.zimbra.common.util.ByteUtil;
/*     */ import com.zimbra.common.util.Pair;
/*     */ import com.zimbra.common.util.ZimbraHttpConnectionManager;
/*     */ import com.zimbra.cs.account.Account;
/*     */ import com.zimbra.cs.account.AuthToken;
/*     */ import com.zimbra.cs.account.Provisioning;
/*     */ import com.zimbra.cs.mailbox.Document;
/*     */ import com.zimbra.cs.mailbox.Flag;
/*     */ import com.zimbra.cs.mailbox.MailItem;
/*     */ import com.zimbra.cs.mailbox.MailItem.Type;
/*     */ import com.zimbra.cs.mailbox.MailServiceException;
/*     */ import com.zimbra.cs.mailbox.Mailbox;
/*     */ import com.zimbra.cs.mailbox.MailboxManager;
/*     */ import com.zimbra.cs.mailbox.Message;
/*     */ import com.zimbra.cs.mailbox.OperationContext;
/*     */ import com.zimbra.cs.mime.Mime;
/*     */ import com.zimbra.cs.mime.ParsedDocument;
/*     */ import com.zimbra.cs.service.FileUploadServlet;
/*     */ import com.zimbra.cs.service.FileUploadServlet.Upload;
/*     */ import com.zimbra.cs.service.UserServlet;
/*     */ import com.zimbra.cs.service.mail.UploadScanner;
/*     */ import com.zimbra.cs.service.mail.UploadScanner.Result;
/*     */ import com.zimbra.cs.service.util.ItemId;
/*     */ import com.zimbra.cs.service.util.ItemIdFormatter;
/*     */ import com.zimbra.soap.ZimbraSoapContext;
/*     */ import java.io.ByteArrayInputStream;
/*     */ import java.io.IOException;
/*     */ import java.io.InputStream;
/*     */ import java.util.Map;
/*     */ import javax.mail.MessagingException;
/*     */ import javax.mail.internet.MimePart;
/*     */ import org.apache.commons.httpclient.Header;
/*     */ import org.apache.commons.httpclient.HttpClient;
/*     */ import org.apache.commons.httpclient.HttpException;
/*     */ import org.apache.commons.httpclient.methods.GetMethod;
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ public class SaveDocument
/*     */   extends DocDocumentHandler
/*     */ {
/*  70 */   private static String[] TARGET_DOC_ID_PATH = { "doc", "id" };
/*  71 */   private static String[] TARGET_DOC_FOLDER_PATH = { "doc", "l" };
/*     */   private static final String DEFAULT_DOCUMENT_FOLDER = "16";
/*     */   
/*  74 */   protected String[] getProxiedIdPath(Element request) { String id = getXPath(request, TARGET_DOC_ID_PATH);
/*  75 */     return id == null ? TARGET_DOC_FOLDER_PATH : TARGET_DOC_ID_PATH;
/*     */   }
/*     */   
/*     */   public Element handle(Element request, Map<String, Object> context)
/*     */     throws ServiceException
/*     */   {
/*  81 */     ZimbraSoapContext zsc = getZimbraSoapContext(context);
/*  82 */     OperationContext octxt = getOperationContext(zsc, context);
/*     */     
/*  84 */     Element docElem = request.getElement("doc");
/*     */     
/*  86 */     Doc doc = null;
/*  87 */     Element response = null;
/*  88 */     boolean success = false;
/*  89 */     Mailbox mbox = null;
/*  90 */     int folderId = 0;
/*     */     try {
/*  92 */       String explicitName = docElem.getAttribute("name", null);
/*  93 */       String explicitCtype = docElem.getAttribute("ct", null);
/*     */       
/*     */ 
/*  96 */       if (explicitName != null) {
/*     */         try {
/*  98 */           explicitName = explicitName.replaceAll("\\\\", "/");
/*  99 */           explicitName = explicitName.substring(explicitName.lastIndexOf("/") + 1);
/*     */         }
/*     */         catch (Exception e) {}
/*     */       }
/*     */       
/*     */ 
/* 105 */       String description = docElem.getAttribute("desc", null);
/* 106 */       ItemId fid = new ItemId(docElem.getAttribute("l", "16"), zsc);
/* 107 */       folderId = fid.getId();
/*     */       
/* 109 */       String id = docElem.getAttribute("id", null);
/* 110 */       int itemId = id == null ? 0 : new ItemId(id, zsc).getId();
/* 111 */       int ver = (int)docElem.getAttributeLong("ver", 0L);
/*     */       
/* 113 */       mbox = getRequestedMailbox(zsc);
/* 114 */       Element attElem = docElem.getOptionalElement("upload");
/* 115 */       Element msgElem = docElem.getOptionalElement("m");
/* 116 */       Element docRevElem = docElem.getOptionalElement("doc");
/* 117 */       if (attElem != null) {
/* 118 */         String aid = attElem.getAttribute("id", null);
/* 119 */         FileUploadServlet.Upload up = FileUploadServlet.fetchUpload(zsc.getAuthtokenAccountId(), aid, zsc.getAuthToken());
/*     */         
/* 121 */         StringBuffer info = new StringBuffer();
/* 122 */         UploadScanner.Result result = UploadScanner.accept(up, info);
/* 123 */         if (result == UploadScanner.REJECT)
/* 124 */           throw MailServiceException.UPLOAD_REJECTED(up.getName(), info.toString());
/* 125 */         if (result == UploadScanner.ERROR) {
/* 126 */           throw MailServiceException.SCAN_ERROR(up.getName());
/*     */         }
/* 128 */         doc = new Doc(up, explicitName, explicitCtype, description);
/* 129 */       } else if (msgElem != null) {
/* 130 */         String part = msgElem.getAttribute("part");
/* 131 */         ItemId iid = new ItemId(msgElem.getAttribute("id"), zsc);
/* 132 */         doc = fetchMimePart(octxt, zsc.getAuthToken(), iid, part, explicitName, explicitCtype, description);
/* 133 */       } else if (docRevElem != null) {
/* 134 */         ItemId iid = new ItemId(docRevElem.getAttribute("id"), zsc);
/* 135 */         int revSource = (int)docRevElem.getAttributeLong("ver", 0L);
/* 136 */         Account sourceAccount = Provisioning.getInstance().getAccountById(iid.getAccountId());
/* 137 */         if (sourceAccount.getId().equals(zsc.getRequestedAccountId())) { Document docRev;
/*     */           Document docRev;
/* 139 */           if (revSource == 0) {
/* 140 */             docRev = mbox.getDocumentById(octxt, iid.getId());
/*     */           } else {
/* 142 */             docRev = (Document)mbox.getItemRevision(octxt, iid.getId(), MailItem.Type.DOCUMENT, revSource);
/*     */           }
/* 144 */           doc = new Doc(docRev);
/*     */         } else {
/* 146 */           doc = new Doc(zsc.getAuthToken(), sourceAccount, iid.getId(), revSource);
/*     */         }
/*     */         
/*     */ 
/* 150 */         if (ver != 0) {
/* 151 */           doc.name = null;
/*     */         }
/*     */       } else {
/* 154 */         String inlineContent = docElem.getAttribute("content");
/* 155 */         doc = new Doc(inlineContent, explicitName, explicitCtype, description);
/*     */       }
/*     */       
/*     */ 
/* 159 */       if (doc.name != null) {
/* 160 */         String guess = MimeDetect.getMimeDetect().detect(doc.name);
/* 161 */         if (guess != null) {
/* 162 */           doc.contentType = guess;
/*     */         }
/*     */       }
/* 165 */       Document docItem = null;
/* 166 */       InputStream is = null;
/*     */       try {
/* 168 */         is = doc.getInputStream();
/*     */       } catch (IOException e) {
/* 170 */         throw ServiceException.FAILURE("can't save document", e);
/*     */       }
/* 172 */       if (itemId == 0)
/*     */       {
/* 174 */         if ((doc.name == null) || (doc.name.trim().equals("")))
/* 175 */           throw ServiceException.INVALID_REQUEST("missing required attribute: name", null);
/* 176 */         if ((doc.contentType == null) || (doc.contentType.trim().equals(""))) {
/* 177 */           throw ServiceException.INVALID_REQUEST("missing required attribute: ct", null);
/*     */         }
/* 179 */         boolean descEnabled = docElem.getAttributeBool("descEnabled", true);
/*     */         try {
/* 181 */           ParsedDocument pd = new ParsedDocument(is, doc.name, doc.contentType, System.currentTimeMillis(), getAuthor(zsc), doc.description, descEnabled);
/*     */           
/* 183 */           String flags = docElem.getAttribute("f", null);
/* 184 */           docItem = mbox.createDocument(octxt, folderId, pd, MailItem.Type.DOCUMENT, Flag.toBitmask(flags));
/*     */         } catch (IOException e) {
/* 186 */           throw ServiceException.FAILURE("unable to create document", e);
/*     */         }
/*     */       }
/*     */       else {
/* 190 */         docItem = mbox.getDocumentById(octxt, itemId);
/* 191 */         if (docItem.getVersion() != ver) {
/* 192 */           throw MailServiceException.MODIFY_CONFLICT(new ServiceException.Argument[] { new ServiceException.Argument("name", doc.name, ServiceException.Argument.Type.STR), new ServiceException.Argument("id", itemId, ServiceException.Argument.Type.IID), new ServiceException.Argument("ver", docItem.getVersion(), ServiceException.Argument.Type.NUM) });
/*     */         }
/*     */         
/* 195 */         String name = docItem.getName();
/* 196 */         if (doc.name != null) {
/* 197 */           name = doc.name;
/*     */         }
/* 199 */         boolean descEnabled = docElem.getAttributeBool("descEnabled", docItem.isDescriptionEnabled());
/* 200 */         docItem = mbox.addDocumentRevision(octxt, itemId, getAuthor(zsc), name, doc.description, descEnabled, is);
/*     */       }
/*     */       
/* 203 */       response = zsc.createElement(MailConstants.SAVE_DOCUMENT_RESPONSE);
/* 204 */       Element m = response.addElement("doc");
/* 205 */       m.addAttribute("id", new ItemIdFormatter(zsc).formatItemId(docItem));
/* 206 */       m.addAttribute("ver", docItem.getVersion());
/* 207 */       m.addAttribute("name", docItem.getName());
/* 208 */       success = true;
/*     */     } catch (ServiceException e) {
/* 210 */       if (e.getCode().equals("mail.ALREADY_EXISTS")) {
/* 211 */         MailItem item = null;
/* 212 */         if ((mbox != null) && (folderId != 0)) {
/* 213 */           item = mbox.getItemByPath(octxt, doc.name, folderId);
/*     */         }
/* 215 */         if ((item != null) && ((item instanceof Document)))
/*     */         {
/* 217 */           throw MailServiceException.ALREADY_EXISTS("name " + doc.name + " in folder " + folderId, doc.name, item.getId(), ((Document)item).getVersion()); }
/* 218 */         if (item != null)
/*     */         {
/* 220 */           throw MailServiceException.ALREADY_EXISTS("name " + doc.name + " in folder " + folderId, doc.name, item.getId());
/*     */         }
/*     */       }
/* 223 */       throw e;
/*     */     } finally {
/* 225 */       if ((success) && (doc != null)) {
/* 226 */         doc.cleanup();
/*     */       }
/*     */     }
/* 229 */     return response;
/*     */   }
/*     */   
/*     */   private Doc fetchMimePart(OperationContext octxt, AuthToken authtoken, ItemId itemId, String partId, String name, String ct, String description) throws ServiceException {
/* 233 */     String accountId = itemId.getAccountId();
/* 234 */     Account acct = Provisioning.getInstance().get(Key.AccountBy.id, accountId);
/* 235 */     if (Provisioning.onLocalServer(acct)) {
/* 236 */       Mailbox mbox = MailboxManager.getInstance().getMailboxByAccount(acct);
/* 237 */       Message msg = mbox.getMessageById(octxt, itemId.getId());
/*     */       try {
/* 239 */         return new Doc(Mime.getMimePart(msg.getMimeMessage(), partId), name, ct);
/*     */       } catch (MessagingException e) {
/* 241 */         throw ServiceException.RESOURCE_UNREACHABLE("can't fetch mime part msgId=" + itemId + ", partId=" + partId, e, new ServiceException.Argument[0]);
/*     */       } catch (IOException e) {
/* 243 */         throw ServiceException.RESOURCE_UNREACHABLE("can't fetch mime part msgId=" + itemId + ", partId=" + partId, e, new ServiceException.Argument[0]);
/*     */       }
/*     */     }
/*     */     
/* 247 */     String url = UserServlet.getRestUrl(acct) + "?auth=co&id=" + itemId + "&part=" + partId;
/* 248 */     HttpClient client = ZimbraHttpConnectionManager.getInternalHttpConnMgr().newHttpClient();
/* 249 */     GetMethod get = new GetMethod(url);
/* 250 */     authtoken.encode(client, get, false, acct.getAttr("zimbraMailHost"));
/*     */     try {
/* 252 */       int statusCode = HttpClientUtil.executeMethod(client, get);
/* 253 */       if (statusCode != 200) {
/* 254 */         throw ServiceException.RESOURCE_UNREACHABLE("can't fetch remote mime part", null, new ServiceException.Argument[] { new ServiceException.InternalArgument("url", url, ServiceException.Argument.Type.STR) });
/*     */       }
/*     */       
/* 257 */       Header ctHeader = get.getResponseHeader("Content-Type");
/* 258 */       ContentType contentType = new ContentType(ctHeader.getValue());
/*     */       
/* 260 */       return new Doc(get.getResponseBodyAsStream(), contentType, name, ct, description);
/*     */     } catch (HttpException e) {
/* 262 */       throw ServiceException.PROXY_ERROR(e, url);
/*     */     } catch (IOException e) {
/* 264 */       throw ServiceException.RESOURCE_UNREACHABLE("can't fetch remote mime part", e, new ServiceException.Argument[] { new ServiceException.InternalArgument("url", url, ServiceException.Argument.Type.STR) });
/*     */     }
/*     */   }
/*     */   
/*     */   private static class Doc {
/*     */     String name;
/*     */     String contentType;
/*     */     String description;
/*     */     private FileUploadServlet.Upload up;
/*     */     private MimePart mp;
/*     */     private String sp;
/*     */     private InputStream in;
/*     */     
/*     */     Doc(MimePart mpart, String filename, String ctype) {
/* 278 */       this.mp = mpart;
/* 279 */       this.name = Mime.getFilename(mpart);
/* 280 */       this.contentType = Mime.getContentType(mpart);
/* 281 */       overrideProperties(filename, ctype);
/*     */     }
/*     */     
/*     */     Doc(FileUploadServlet.Upload upload, String filename, String ctype, String d) {
/* 285 */       this.up = upload;
/* 286 */       this.name = upload.getName();
/* 287 */       this.contentType = upload.getContentType();
/* 288 */       this.description = d;
/* 289 */       overrideProperties(filename, ctype);
/* 290 */       if (this.contentType == null) {
/* 291 */         this.contentType = "application/octet-stream";
/*     */       }
/*     */     }
/*     */     
/*     */     Doc(String content, String filename, String ctype, String d) {
/* 296 */       this.sp = content;
/* 297 */       this.description = d;
/* 298 */       overrideProperties(filename, ctype);
/* 299 */       if (this.contentType != null) {
/* 300 */         this.contentType = new ContentType(this.contentType).setParameter("charset", "utf-8").toString();
/*     */       }
/*     */     }
/*     */     
/*     */     Doc(InputStream in, ContentType ct, String filename, String ctype, String d) {
/* 305 */       this.in = in;
/* 306 */       this.description = d;
/* 307 */       this.name = (ct == null ? null : ct.getParameter("name"));
/* 308 */       if (this.name == null) {
/* 309 */         this.name = "New Document";
/*     */       }
/* 311 */       this.contentType = (ct == null ? null : ct.getContentType());
/* 312 */       if (this.contentType == null) {
/* 313 */         this.contentType = "application/octet-stream";
/*     */       }
/* 315 */       overrideProperties(filename, ctype);
/*     */     }
/*     */     
/*     */     Doc(Document d) throws ServiceException {
/* 319 */       this.in = d.getContentStream();
/* 320 */       this.contentType = d.getContentType();
/* 321 */       this.name = d.getName();
/* 322 */       this.description = d.getDescription();
/*     */     }
/*     */     
/* 325 */     Doc(AuthToken auth, Account acct, int id, int ver) throws ServiceException { String url = UserServlet.getRestUrl(acct) + "?fmt=native&disp=attachment&id=" + id;
/* 326 */       if (ver > 0) {
/* 327 */         url = url + "&ver=" + ver;
/*     */       }
/* 329 */       Pair<Header[], byte[]> resource = UserServlet.getRemoteResource(auth.toZAuthToken(), url);
/* 330 */       int status = 0;
/* 331 */       for (Header h : (Header[])resource.getFirst()) {
/* 332 */         if (h.getName().equalsIgnoreCase("X-Zimbra-Http-Status")) {
/* 333 */           status = Integer.parseInt(h.getValue());
/* 334 */         } else if (h.getName().equalsIgnoreCase("X-Zimbra-ItemName")) {
/* 335 */           this.name = h.getValue();
/* 336 */         } else if (h.getName().equalsIgnoreCase("Content-Type")) {
/* 337 */           this.contentType = h.getValue();
/*     */         }
/*     */       }
/* 340 */       if (status != 200) {
/* 341 */         throw ServiceException.RESOURCE_UNREACHABLE("http error " + status, null, new ServiceException.Argument[0]);
/*     */       }
/* 343 */       this.in = new ByteArrayInputStream((byte[])resource.getSecond());
/*     */     }
/*     */     
/*     */     private void overrideProperties(String filename, String ctype) {
/* 347 */       if ((filename != null) && (!filename.trim().equals(""))) {
/* 348 */         this.name = filename;
/*     */       }
/* 350 */       if ((ctype != null) && (!ctype.trim().equals(""))) {
/* 351 */         this.contentType = ctype;
/*     */       }
/*     */     }
/*     */     
/*     */     public InputStream getInputStream() throws IOException {
/*     */       try {
/* 357 */         if (this.up != null)
/* 358 */           return this.up.getInputStream();
/* 359 */         if (this.mp != null)
/* 360 */           return this.mp.getInputStream();
/* 361 */         if (this.sp != null)
/* 362 */           return new ByteArrayInputStream(this.sp.getBytes("utf-8"));
/* 363 */         if (this.in != null) {
/* 364 */           return this.in;
/*     */         }
/* 366 */         throw new IOException("no contents");
/*     */       }
/*     */       catch (MessagingException e) {
/* 369 */         throw new IOException(e.getMessage());
/*     */       }
/*     */     }
/*     */     
/*     */     public void cleanup() {
/* 374 */       if (this.up != null) {
/* 375 */         FileUploadServlet.deleteUpload(this.up);
/*     */       }
/* 377 */       ByteUtil.closeStream(this.in);
/*     */     }
/*     */   }
/*     */   
/*     */   public boolean isReadOnly() {
/* 382 */     return false;
/*     */   }
/*     */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/service/doc/SaveDocument.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */